<template>
  <!-- 修改 -->
  <el-dialog
    v-model="dialogVisible"
    :title="formData.id === undefined ? '新增菜单' : '修改菜单'"
    @closed="closedDialog"
    width="50%"
    :close-on-click-modal="false"
  >
    <el-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      label-width="150px"
      label-position="right"
      v-loading="formLoading"
    >
      <el-form-item
        v-show="formData.parentMenuTitle !== undefined"
        label="父级菜单"
        prop="parentTitle"
      >
        <el-input disabled v-model="formData.parentMenuTitle" />
      </el-form-item>
      <el-form-item label="菜单标题" prop="menuTitle">
        <el-input
          v-model="formData.menuTitle"
          placeholder="请输入菜单标题"
          maxlength="16"
        />
      </el-form-item>
      <el-form-item label="菜单编码" prop="menuCode">
        <el-input
          v-model="formData.menuCode"
          placeholder="请输入自定义编码"
          maxlength="128"
        />
      </el-form-item>
      <el-form-item label="菜单类型" prop="menuType">
        <el-select v-model="formData.menuType" placeholder="请选择菜单类型">
          <el-option
            v-for="item in MENU_TYPE_OPTIONS"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="菜单图标" prop="menuIcon">
        <el-row style="width: 100%">
          <IconSelect v-model="formData.menuIcon"/>
        </el-row>
      </el-form-item>
      <el-form-item label="菜单路由" prop="menuPath">
        <el-input
          v-model="formData.menuPath"
          placeholder="请输入菜单自定义路由"
          maxlength="128"
        />
        <el-alert
          title="目录开头必须补充符号：/,菜单不能添加"
          type="warning"
          show-icon
          :closable="false"
        />
      </el-form-item>
      <!-- 目录存在默认重定向-->
      <el-form-item
        v-if="0 === formData.menuType"
        label="重定向路由"
        prop="redirect"
      >
        <el-input
          v-model="formData.redirect"
          placeholder="默认指向的路由"
          maxlength="256"
        />
      </el-form-item>
      <el-form-item label="菜单资源路径" prop="component">
        <el-input
          v-model="formData.component"
          placeholder="请输入菜单物理路径"
        />
      </el-form-item>
      <el-form-item label="排序" prop="orderNum">
        <el-input-number
          v-model="formData.orderNum"
          placeholder="请输入排序"
          maxlength="3"
        />
      </el-form-item>
      <el-form-item label="隐藏" prop="hidden">
        <el-select v-model="formData.hidden" placeholder="请选择">
          <el-option
            v-for="item in MENU_HIDDEN_OPTIONS"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="菜单描述" prop="description">
        <el-input
          v-model="formData.description"
          type="textarea"
          placeholder="请输入菜单描述"
          maxlength="500"
          show-word-limit
          :rows="4"
        />
      </el-form-item>
    </el-form>

    <template #footer>
      <el-button @click="closedDialog">取消</el-button>
      <el-button
        type="primary"
        @click="handleCreateOrUpdate"
        :loading="loading"
      >
        确认
      </el-button>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, onBeforeMount } from "vue";
import MenuAPI, { type MenuVO } from "@/api/system/sys/menu";
import { type FormInstance, type FormRules } from "element-plus";
import { cloneDeep } from "lodash-es";

import { ICON_OPTIONS, MENU_TYPE_OPTIONS, MENU_HIDDEN_OPTIONS } from "./const";

/**
 * 菜单编辑详情页面
 */
defineOptions({
  name: "EditMenuDetailsDialog",
});
const props = defineProps({
  menuId: {
    type: String,
    required: false,
  },
  parentMenu: {
    type: Object as unknown as () => MenuVO,
    required: false,
  },
  closedDialog: {
    type: Function,
    required: true,
  },
});

/** 表单初始化 */
const DEFAULT_FORM_DATA: MenuVO = {
  id: props.menuId,
  /** 菜单父级id */
  parentId: undefined,
  /** 菜单父级标题 */
  parentMenuTitle: props.parentMenu?.menuTitle,
  /** (0:目录|1:菜单) */
  menuType: undefined,
  /** 菜单编码 */
  menuCode: undefined,
  /** 菜单标题 */
  menuTitle: undefined,
  /** 菜单图标 */
  menuIcon: undefined,
  /** 菜单路径（路径别名） */
  menuPath: "/",
  /** 菜单路径(菜单url地址) */
  component: undefined,
  /** 页面组件(页面目录地址) */
  redirect: undefined,
  /** 是否隐藏菜单（0不隐藏,1隐藏） */
  hidden: 0,
  /**排序 */
  orderNum: undefined,
  /** 菜单描述 */
  description: undefined,
};
/** 表单对象 */
const formData = ref<MenuVO>(cloneDeep(DEFAULT_FORM_DATA));
const formRef = ref<FormInstance | null>(null);
/** 表单校验格式 */
const formRules: FormRules<any> = {
  menuCode: [
    { required: true, message: "请输入菜单编码", trigger: "blur" },
    { max: 128, message: "长度在128以内个字符", trigger: "blur" },
  ],
  menuTitle: [
    { required: true, message: "请输入菜单标题", trigger: "blur" },
    { min: 1, max: 16, message: "长度在16以内个字符", trigger: "blur" },
  ],
  menuPath: [
    { required: true, message: "请输入菜单路径", trigger: "blur" },
    { min: 1, max: 128, message: "长度在128以内个字符", trigger: "blur" },
  ],
  redirect: [
    { required: true, message: "请输入重定向地址", trigger: "blur" },
    { max: 128, trigger: "blur" },
  ],
  orderNum: [{ type: "number", message: "排序必须为数字值" }],
  description: [
    { message: "请输入菜单描述", trigger: "blur" },
    { max: 500, message: "长度在500以内个字符", trigger: "blur" },
  ],
};
const dialogVisible = ref<boolean>(true);
const loading = ref<boolean>(false);
const formLoading = ref<boolean>(false);

/** 新增或者更新 */
const handleCreateOrUpdate = () => {
  formRef.value?.validate((valid: boolean, fields) => {
    if (!valid) return console.error("表单校验不通过", fields);

    loading.value = true;
    if (formData.value.id === undefined) {
      // 新增
      formData.value.parentId = "root";
      MenuAPI.addSysMenuApi(formData.value)
        .then(() => {
          ElMessage.success("操作成功");
        })
        .finally(() => {
          loading.value = false;
          props.closedDialog(true);
        });
    } else {
      // 更新
      MenuAPI.putSysMenuApi(formData.value.id, formData.value)
        .then(() => {
          ElMessage.success("操作成功");
        })
        .finally(() => {
          loading.value = false;
          props.closedDialog(true);
        });
    }
  });
};

/** 关闭弹窗 */
const closedDialog = () => {
  props.closedDialog(false);
};

/** 页面渲染完成后初始化 */
onBeforeMount(async () => {
  if (props.menuId) {
    formLoading.value = true;
    MenuAPI.getSysMenuApi(props.menuId)
      .then((res) => {
        const { data } = res;
        formData.value = data;
      })
      .finally(() => {
        formLoading.value = false;
      });
  }
});
</script>

<style lang="scss" scoped>
.el-alert {
  margin: 5px 0 0;
  height: 40px;
}
.el-alert:first-child {
  margin: 0;
}
</style>
